package com.sunxd.zookeeper.use;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat;
import org.springframework.lang.NonNull;
import org.springframework.stereotype.Component;

/**
 * @author: 作者名称
 * @date: 2021-06-28 02:47
 **/
@Component
@Data
@Slf4j
public class ZkMyselfUtil {

    private ZooKeeper zooKeeper;

    private final static String RETURN_STRING_NULL = null;


    //***//**************************** 创建节点数据 ********************************************************************************
    /**
     * 创建永久节点
     *
     * @param path 路径
     * @param data 数据
     * @return 返回值，成功 路径path,失败 @EMPTY_STRING
     */
    public String createP(@NonNull String path, String data) {
        try {
            return zooKeeper.create(path, data.getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
        } catch (Exception e) {
            log.error(" createP error path:{},data:{}", path, data);
        }
        return RETURN_STRING_NULL;
    }

    //***//**************************** 设置数据 ********************************************************************************
    /**
     * 设置数据
     * @param path path
     * @param data data
     * @param version version
     * @return Stat
     */
    public Stat setDataWithVersion(@NonNull String path, String data, int version) {
        try {
            return zooKeeper.setData(path, data.getBytes(), version);
        } catch (Exception e) {
            log.error(" setDataWithVersion error path:{}, data:{}, version:{}", path, data, version);
        }
        return null;
    }

    /**
     * 设置数据
     * @param path path
     * @param data data
     * @return Stat
     */
    public Stat setData(@NonNull String path, String data) {
        return setDataWithVersion(path, data, -1);

    }

    //***//**************************** 删除数据 ********************************************************************************
    /**
     * 删除数据
     * @param path path
     * @param version version
     */
    public void deleteWithVersion(@NonNull String path, int version) {
        try {
             zooKeeper.delete(path, version);
        } catch (Exception e) {
            log.error(" setDataWithVersion error path:{},version:{}", path, version);
        }
    }

    /**
     * 删除数据
     * @param path path
     */
    public void delete(@NonNull String path) {
        try {
            deleteWithVersion(path, -1);
        } catch (Exception e) {
            log.error(" setDataWithVersion error path:{}", path);
        }
    }

    //***//**************************** 获取数据 ********************************************************************************
    /**
     * 获取数据
     *
     * @param path  path
     * @param watch watch  true:走连接的watcher false:不走
     * @return String
     */
    public String getData(@NonNull String path, Boolean watch) {
        Stat stat = new Stat();
        try {
            byte[] data = zooKeeper.getData(path, watch, stat);
            return new String(data);
        } catch (Exception e) {
            log.error(" getDataWithWatcher error path:{} ", path, e);
        }
        return RETURN_STRING_NULL;
    }

    /**
     * 获取数据并设置监听
     *
     * @param path    path
     * @param watcher watcher 回掉方法（增删改数据）
     * @return String
     */
    public String getDataWithWatcher(@NonNull String path, Watcher watcher) {
        Stat stat = new Stat();
        try {
            byte[] data = zooKeeper.getData(path, watcher, stat);
            return new String(data);
        } catch (Exception e) {
            log.error(" getDataWithWatcher error path:{} ", path, e);
        }
        return RETURN_STRING_NULL;
    }

    /**
     * 回掉方式获取数据并设置监听
     *
     * @param path  path
     * @param watch watch  true:走连接的watcher false:不走
     * @param ctx   ctx  上下文穿参数
     */
    public void getDataWithDataCallbackAndBWatch(@NonNull String path, Boolean watch, AsyncCallback.DataCallback dataCallback, Object ctx) {
        try {
            zooKeeper.getData(path, watch, dataCallback, ctx);
        } catch (Exception e) {
            log.error(" getDataWithDataCallbackWatcher error path:{} , watcher:{}, ctx:{}", path, watch, ctx, e);
        }
    }

    /**
     * 回掉方式获取数据并设置监听
     *
     * @param path    path
     * @param watcher watcher 回掉方法（删改数据）
     */
    public void getDataWithDataCallbackWatch(@NonNull String path, Watcher watcher, AsyncCallback.DataCallback dataCallback, Object ctx) {
        try {
            zooKeeper.getData(path, watcher, dataCallback, ctx);
        } catch (Exception e) {
            log.error(" getDataWithDataCallbackWatcher error path:{} , ctx:{}", path, ctx, e);
        }
    }


    public void exists(@NonNull String path, Watcher watcher, AsyncCallback.StatCallback cb, Object ctx){
        zooKeeper.exists(path,watcher,cb,ctx);
    }




}
